<?php
require_once 'nrg/ut/suite.class.js';
?>

var Nrg_Ut_TestCase = new Class({
	
	name: null,
	
	ParentSuite: null,
	
	//--------------------------------------------------------------------------
	//--------------------------------------------------------------------------
	
	initialize: function(name)
	{
		if ( ! instanceOf(name, String) ) {
			throw 'The name must be a string';
		}
		this.name = name;
	},
	
	//--------------------------------------------------------------------------
	
	getName: function()
	{
		return this.name;
	},
	
	//--------------------------------------------------------------------------
	
	run: function()
	{
		if ( instanceOf(this.setUpBeforeClass, Function) ) {
			this.setUpBeforeClass();
		}
		
		for ( var i in this ) {
			if ( 'function' == typeof this[i] ) {
				if ( this[i].$name && 'test' == this[i].$name.substr(0, 4) ) {
					this.getParentSuite().getParentApp().logFn(this[i].$name);
					if ( instanceOf(this.setUp, Function) ) {
						this.setUp();
					}
					this[i]();
					if ( instanceOf(this.tearDown, Function) ) {
						this.tearDown();
					}
				}
			}
		}
		
		if ( instanceOf(this.tearDownAfterClass, Function) ) {
			this.tearDownAfterClass();
		}
	},
	
	//--------------------------------------------------------------------------
	
	setParentSuite: function(ParentSuite)
	{
		if ( ! instanceOf(ParentSuite, Nrg_Ut_Suite) ) {
			throw 'The parameter must be an instance of Nrg_Ut_Suite';
		}
		this.ParentSuite = ParentSuite;
	},
	
	//--------------------------------------------------------------------------
	
	getParentSuite: function()
	{
		return this.ParentSuite;
	},
	
	//--------------------------------------------------------------------------
	
	logAssert: function(res, sysmsg, msg)
	{
		this.getParentSuite().getParentApp().logAssert(res, sysmsg, msg);
	},
	
	//--------------------------------------------------------------------------
	
	assertEquals: function(expected, actual, msg)
	{
		var res = (expected == actual);
		sysmsg = '';
		if ( ! res ) {
			sysmsg = 'Faild asserting that ' + expected + ' == ' + actual;
		}
		this.logAssert(res, sysmsg, msg);
	},
	
	//--------------------------------------------------------------------------
	
	assertNotEquals: function(expected, actual, msg)
	{
		var res = ! (expected == actual);
		sysmsg = '';
		if ( ! res ) {
			sysmsg = 'Faild asserting that ' + expected + ' != ' + actual;
		}
		this.logAssert(res, sysmsg, msg);
	},
	
	//--------------------------------------------------------------------------
	
	assertTrue: function(val, msg)
	{
		if ( val ) {
			this.logAssert(true);
		}
		else {
			var sysmsg = 'Failed asserting that ' + val + ' == true';
			this.logAssert(false, sysmsg, msg);
		}
	},
	
	//--------------------------------------------------------------------------
	
	assertFalse: function(val, msg)
	{
		if ( ! val ) {
			this.logAssert(true);
		}
		else {
			var sysmsg = 'Failed asserting that ' + val + ' == false';
			this.logAssert(false, sysmsg, msg);
		}
	},
	
	//--------------------------------------------------------------------------
	
	assertContains: function(needle, haystack, msg)
	{
		var res = false;
		for ( i in haystack ) {
			if ( needle == haystack[i] ) {
				res = true;
				break;
			}
		}
		
		var sysmsg = 'Failed asserting that '
			+ typeOf(haystack) +  ' contains value ' + needle;
		
		this.logAssert(res, sysmsg, msg);
	},
	
	//--------------------------------------------------------------------------
	
	/**
	 * Checks if a object that can be itarate through contains only
	 * given type of data. Be warned, that arrays in JS more often then
	 * not contain additional, unexpected elements like functions added
	 * to each array object by usting prototype directive.
	 */
	assertContainsOnly: function(type, haystack, msg)
	{
		var res = true;
		var i = 0;
		var testHaystack;
		
		if ( 'object' == typeOf(haystack) && ! haystack.each ) {
			testHaystack = new Object(haystack);
		}
		else {
			testHaystack = Array.from(haystack);
		}
		
		Object.each(testHaystack, function(el){
			if ( ! Nrg_Debug_Type.cmpType(el, type) ) {
				res = false;
			}
			if ( res ) {
				++i;
			}
		}.bind(this));
		
		var type_to_str = Nrg_Debug_Type.typeToStr(type);
		if ( 'type' == type_to_str ) {
			type_to_str = 'specified type';
		}
		var sysmsg = 'Faild asserting that '
			+ typeOf(haystack) + ' contains only ' + type_to_str
			+ ' - on index = ' + i;
		
		this.logAssert(res, sysmsg, msg);
	},
	
	//--------------------------------------------------------------------------
	
	assertInstanceOf: function(Obj, ClassObj, msg)
	{
		if ( instanceOf(Obj, ClassObj) ) {
			this.logAssert(true);
		}
		else {
			var sysmsg = 'Failed asserting that object is instance of class';
			this.logAssert(false, sysmsg, msg);
		}
	},
	
	//--------------------------------------------------------------------------
	
	assertTypeOf: function(Obj, type, msg)
	{
		if ( typeOf(Obj) == type ) {
			this.logAssert(true);
		}
		else {
			var sysmsg = 'Failed asserting that object is type of "'
				+ type + '". Actual type: "' + typeOf(Obj) + '"';
			this.logAssert(false, sysmsg, msg);
		}
	}
	
	//--------------------------------------------------------------------------
	
});
